package analysis;
import io.*;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
public class GetUserPopularity {
	private static final String inputFile = "UserInteraction.txt";
	private static final String userPopularityFile = "user_popularity_sortByScore.txt";
	static Map<Integer, UserPopularity> allUser;
	public static Map<Integer,Double> userScore; 
	static void loadData(String fileName)	throws IOException{
		allUser = new HashMap<Integer, UserPopularity>();
		BufferedReader br = new BufferedReader(new FileReader(fileName));
		String line = br.readLine();
		int lineCount = 0;
		while(line != null && line.length() > 0)	{
			dealwithLine(line);
			line = br.readLine();
			if(++lineCount % 100000 == 0)
				System.out.println(lineCount);
		}
	}
	static void dealwithLine(String line)	{
		String[] currentLines = line.split("\\s+");
		Integer id = new Integer(currentLines[1]);
		UserPopularity user = null;
		user = allUser.get(id);
		boolean needAdd = false;
		if(user == null)	{
			user = new UserPopularity();
			user.id = id;
			needAdd = true;
		}
		user.recCount += new Integer(currentLines[2]);
		user.clickCount += new Integer(currentLines[3]);
		user.msgCount += new Integer(currentLines[4]);
		if(needAdd){
			allUser.put(id, user);
		}
	}
	static void caculatedAndSort()	{
		Iterator it = allUser.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<Integer, UserPopularity> entry = (Entry<Integer, UserPopularity>) it.next();
			UserPopularity user = entry.getValue();
			if(user.recCount == 0)
				user.clickRate = 0;
			else 
				user.clickRate = 1.0*user.clickCount/user.recCount;
			if(user.clickCount == 0)
				user.msgRate = 0;
			else 
				user.msgRate = 1.0*user.msgCount/user.clickCount;
			user.score = (3*user.msgCount + user.clickCount)/(Math.sqrt(user.recCount)+1);
		}
		allUser = sortByValue(allUser);
		
	}
	static void outputData(String fileName) throws IOException	{
		BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
		Iterator it = allUser.entrySet().iterator();
		while(it.hasNext()){
			Map.Entry<Integer, UserPopularity> entry = (Entry<Integer, UserPopularity>) it.next();
			UserPopularity user = entry.getValue();
			bw.write(entry.getKey() + " " + user.toString());bw.newLine();
		}
		bw.close();
		
	}
	public static void LoadPopularityScore() throws IOException	{
		BufferedReader bReader = new BufferedReader(new FileReader(userPopularityFile));
		allUser = new HashMap<Integer,UserPopularity>();
		userScore = new HashMap<Integer,Double>();
		String line = bReader.readLine();
		while(line!=null && line.length() > 0)	{
			String[] currentLines = line.split("\\s+");
			int id = new Integer(currentLines[0]);
			double score = new Double(currentLines[currentLines.length-1]);
			//System.out.println(id + " " +score);
			UserPopularity user = new UserPopularity();
			user.id = id;
			user.score = score;
			allUser.put(id, user);
			userScore.put(id, score);
			line = bReader.readLine();
			//break;
		}
		
	}
	
	static Map sortByValue(Map<Integer,UserPopularity> map) {
	     List list = new LinkedList(map.entrySet());
	     Collections.sort(list, new UserPopularityComparator() );

	    Map result = new LinkedHashMap();
	    for (Iterator it = list.iterator(); it.hasNext();) {
	        Map.Entry entry = (Map.Entry)it.next();
	        result.put(entry.getKey(), entry.getValue());
	    }
	    return result;
	} 
	public static void main(String[] args) throws IOException{
		//loadData(inputFile);
		//caculatedAndSort();
		LoadPopularityScore();
		outputData("user_popularity_sortByScore2.txt");
	}
}
class UserPopularity {
	int id = 0;
	double clickRate = 0;
	double msgRate= 0;
	double score = 0;
	int recCount = 0;
	int clickCount = 0;
	int msgCount = 0;
	public String toString()	{
		return clickRate + " " + msgRate + " " + recCount + " " + clickCount + " " + msgCount+ " "+ score;
	}
}
class UserPopularityComparator implements Comparator	{

	@Override
	public int compare(Object o1, Object o2) {
		UserPopularity u1 = ((Map.Entry<Integer, UserPopularity>)o1).getValue();
		UserPopularity u2 = ((Map.Entry<Integer, UserPopularity>)o2).getValue();

		// TODO Auto-generated method stub
		/*
		if(u1.clickRate > u2.clickRate)
			return -1;
		else if(u1.clickRate < u2.clickRate)
			return 1;
		else {
			if(u1.msgRate > u2.msgRate)
				return -1;
			else if(u1.msgRate < u2.msgRate)
				return 1;
			else {
				return 0;
				
			}
			
		}
		*/
		//return u2.msgCount - u1.msgCount;
		if(u1.score < u2.score)
			return 1;
		else 
			return -1;
	}
	

}